广度优先搜索(迷宫问题2)

迷宫问题求最短路径


在结构体中多加入一个road记录该结构体的来源,然后存入数组,再将数组反向输出即可。

/*
S01E
0010
0010
0100
0000

S010
0000
0010
01E0
0000

S011
0011
1111
1111
111E
*/
#include<stdio.h>
#include<string.h>
typedef struct node
{
    int x;
    int y;
    int step;
    int road;
}Node;
int main()
{
    int stratx,straty,i,j,i1,j1,m=5,n=4,head=0,tail=0;
    //scanf("%d %d",&m,&n);
    char map[m][n];
    int flag[m][n],next[4][2]={0,1,1,0,0,-1,-1,0};
    Node s[m*n],turn[m*n];
    memset(map,0,sizeof(map));
    memset(flag,0,sizeof(flag));
    memset(s,0,sizeof(s));
    for (i=0;i<m;i++)
    gets(map[i]);
    //查找起点 
    for (i=0;i<m;i++)
    {
        for (j=0;j<n;j++)
        {
            if (map[i][j]=='S')
            {
                flag[i][j]=1;
                //记录起点
                stratx=i;
                straty=j; 
                //步数为0 
                s[tail].step=0;
                //改点为起点,所以前一个点设为0 
                s[tail].road=0;
                tail++;
            }
        }
    }
    //不断循环 
    while (head<tail)
    {
        for (i=0;i<4;i++)
        {
            //记录下一个点的坐标 
            i1=s[head].x+next[i][0];
            j1=s[head].y+next[i][1];
            //判断越界 
            if (i1<0||i1>=m||j1<0||j1>=n)
            continue;
            //入队
            if (flag[i1][j1]==0&&(map[i1][j1]=='0'||map[i1][j1]=='E'))
            {
                flag[i1][j1]=1;
                s[tail].x=i1;
                s[tail].y=j1;
                //步数加一 
                s[tail].step=s[head].step+1;
                //由于一个点可以产生多个点,所以我们选择用产生的点来记录前一个点 
                //此时s[tail]是由s[head]产生的,所以将head存入s[tail].road中 
                s[tail].road=head;
                tail++;
            }
            //判断终点
            if (map[i1][j1]=='E')
            {
                //由于后面head没用了,所以用head记录走的步数 
                head=s[tail-1].step;
                tail--;
                //存入数组turn 
                for (i=0;tail!=0;i++)//起点的tail==0 
                {
                    //printf("%d %d\n",s[tail].x,s[tail].y);
                    turn[i].x=s[tail].x;
                    turn[i].y=s[tail].y;
                    tail=s[tail].road;
                }
                printf("%d %d\n",stratx,straty);
                //反向输出 
                for (i--;i>=0;i--)
                printf("%d %d\n",turn[i].x,turn[i].y);
                printf("该地图至少走%d步可以到达终点",head);
                return 0;
            }
        }
        //每算完一个点的四个方向就将这个点出队 
        head++;
    }
    //若上面找不到,则无解 
    printf("Are you kidding me?\n这个地图有解?"); 
}
下面是一个简单的 C++ 广度优先搜索迷宫问题代码示例: ```c++ #include <iostream> #include <queue> using namespace std; const int MAXN = 100; // 迷宫的最大行列数 int maze[MAXN][MAXN]; // 迷宫地图 int vis[MAXN][MAXN]; // 标记每个位置是否已经走过 int n, m; // 迷宫的行列数 int sx, sy; // 起点坐标 int ex, ey; // 终点坐标 // 定义一个结构体表示坐标 struct Coordinate { int x, y; }; // 定义四个方向 const int dx[4] = {1, -1, 0, 0}; const int dy[4] = {0, 0, 1, -1}; // 判断坐标是否在迷宫范围内 bool isInside(int x, int y) { return x >= 0 && x < n && y >= 0 && y < m; } // 广度优先搜索函数 int bfs() { // 定义一个队列 queue<Coordinate> q; // 将起点入队 q.push({sx, sy}); // 标记起点已经走过 vis[sx][sy] = 1; // 定义一个步数计数器 int steps = 0; // 开始搜索 while (!q.empty()) { // 获取队首坐标 Coordinate cur = q.front(); q.pop(); // 判断是否到达终点 if (cur.x == ex && cur.y == ey) { return steps; } // 枚举四个方向 for (int i = 0; i < 4; i++) { int nx = cur.x + dx[i]; int ny = cur.y + dy[i]; // 判断新坐标是否在迷宫范围内,并且没有走过,并且不是障碍物 if (isInside(nx, ny) && !vis[nx][ny] && maze[nx][ny] != 1) { // 将新坐标入队 q.push({nx, ny}); // 标记新坐标已经走过 vis[nx][ny] = 1; } } // 步数加1 steps++; } // 没有找到终点,返回-1 return -1; } int main() { // 读入迷宫地图和起点终点坐标 cin >> n >> m >> sx >> sy >> ex >> ey; for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { cin >> maze[i][j]; } } // 输出最短步数 cout << bfs() << endl; return 0; } ``` 在这个代码示例中,我们使用一个二维数组 `maze` 表示迷宫地图,其中 `0` 表示可以通过的位置,`1` 表示障碍物。我们还使用一个二维数组 `vis` 标记每个位置是否已经走过,初始值都是 `0`。我们使用一个结构体 `Coordinate` 表示坐标,其中包括 `x` 和 `y` 两个属性。我们使用两个变量 `sx` 和 `sy` 表示起点坐标,使用 `ex` 和 `ey` 表示终点坐标。 我们使用一个广度优先搜索函数 `bfs` 进行搜索,该函数的返回值是最短步数。在搜索过程中,我们使用一个队列 `q` 存储待搜索的坐标。每次从队首取出一个坐标,枚举四个方向,如果新坐标没有走过,并且不是障碍物,就将其入队,并标记为已经走过。如果搜索到了终点,就返回当前步数。如果队列为空,说明没有找到终点,返回-1。 在 `main` 函数中,我们读入迷宫地图和起点终点坐标,然后调用 `bfs` 函数进行搜索,并输出最短步数。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值